package frame;

import gameBasics.GameModel;
import gameBasics.PropertyManager;
import tank.Dir;
import tank.Tank;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Objects;

public abstract class GameFrame extends Frame {

    //游戏窗口的宽度和高度
    public static final int GAME_WIDTH = Objects.requireNonNull(PropertyManager.getInt("gameWidth"));
    public static final int GAME_HEIGHT = Objects.requireNonNull(PropertyManager.getInt("gameHeight"));
    public GameModel gameModel = GameModel.getInstance();

    //无参构造方法
    public GameFrame(){
        setSize(GAME_WIDTH, GAME_HEIGHT);  //设置窗口的宽高
        setTitle("坦克大战");                //设置窗口标题
        setVisible(true);                  //显示窗口
        setResizable(false);               //窗口大小能否改变
        setLocationRelativeTo(null);       //使窗口居中

        addKeyListener(new MyKeyListener());

        //添加窗口监听器(监听windowClosing事件, 当点击窗口的关闭键时触发)
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
    }

    //双缓冲解决闪烁问题(游戏制作中常用的概念)
    Image offScreenImage = null;
    @Override
    public void update(Graphics graphics){
        if(offScreenImage == null){
            offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT);
        }
        Graphics gOffScreen = offScreenImage.getGraphics();
        Color color = gOffScreen.getColor();
        gOffScreen.setColor(Color.BLACK);
        gOffScreen.fillRect(0,0,GAME_WIDTH,GAME_HEIGHT);
        gOffScreen.setColor(color);
        paint(gOffScreen);
        graphics.drawImage(offScreenImage,0,0,null);
    }

    //窗口需要重新绘制时系统会自动调用paint方法, Graphics对象即为画笔
    @Override
    public abstract void paint(Graphics graphics);

    /**
     * 键盘监听: 应用于主坦克移动
     */
    class MyKeyListener extends KeyAdapter{
        boolean bL = false;     //左键是否被按下
        boolean bU = false;     //上键是否被按下
        boolean bR = false;     //右键是否被按下
        boolean bD = false;     //下键是否被按下

        //键盘被按下时调用
        @Override
        public void keyPressed(KeyEvent e) {
            //获取被按下的键
            int key = e.getKeyCode();

            switch (key){
                case KeyEvent.VK_LEFT -> bL = true;       //向左移动
                case KeyEvent.VK_UP -> bU = true;         //向上移动
                case KeyEvent.VK_RIGHT -> bR = true;      //向右移动
                case KeyEvent.VK_DOWN -> bD = true;       //向下移动
            }

            setMainTankDir();
        }

        //键盘抬起时调用
        @Override
        public void keyReleased(KeyEvent e) {
            //获取抬起的键
            int key = e.getKeyCode();

            switch (key){
                case KeyEvent.VK_LEFT -> bL = false;       //向左移动
                case KeyEvent.VK_UP -> bU = false;         //向上移动
                case KeyEvent.VK_RIGHT -> bR = false;      //向右移动
                case KeyEvent.VK_DOWN -> bD = false;       //向下移动
                case KeyEvent.VK_SPACE -> gameModel.getMainTank().fire(); //开火
            }

            setMainTankDir();
        }

        /**
         * 设置主坦克方向
         */
        private void setMainTankDir() {
            Tank mainTank = gameModel.getMainTank();

            if(!bL && !bU && !bR && !bD){
                mainTank.setMovingState(false);
            }else {
                mainTank.setMovingState(true);

                if(bL) mainTank.setDir(Dir.LEFT);
                if(bU) mainTank.setDir(Dir.UP);
                if(bR) mainTank.setDir(Dir.RIGHT);
                if(bD) mainTank.setDir(Dir.DOWN);
            }
        }
    }

}